#ifndef TAC_H
#define	TAC_H

#include <stdio.h>
#include "symbol_table.h"

#define    TAC_UNDEF 	 0
#define	   TAC_ADD 	 1
#define	   TAC_SUB	 2
#define	   TAC_MUL	 3
#define	   TAC_DIV	 4
#define    TAC_SYMBOL	 5
#define    TAC_COPY	 6
#define    TAC_JZERO  	 7
#define    TAC_LABEL  	 8
#define    TAC_GE	 9
#define    TAC_LE	10
#define    TAC_NE	11
#define    TAC_EQ	12
#define    TAC_LESS	13
#define    TAC_GRT	14
#define    TAC_AND	15
#define    TAC_OR	16
#define    TAC_GOTO	17
#define    TAC_CALL	18
#define    TAC_NOT	19
#define    TAC_VEC	20
#define    TAC_PRINT_INT 21
#define    TAC_RETURN	22
#define    TAC_ARG	23
#define    TAC_FUNC_BEGIN   24
#define    TAC_FUNC_END 25
#define    TAC_REF 26
#define    TAC_INT_TYPE 27
#define    TAC_BYTE_TYPE 28
#define    TAC_VAR_DEF 29
#define    TAC_FUNC_PARAM   30
#define    TAC_FUNC_CMD 31
#define    TAC_FUNC_CMD_BEGIN   32
#define    TAC_FUNC_CMD_END 33
#define    TAC_VEC_DEF 34
#define    TAC_VEC_REF 35
#define    TAC_VEC_COPY	 36
#define    TAC_PRINT_STR 37

typedef struct tac_node {
    int type;
    HASH_NODE *res;
    HASH_NODE *op1;
    HASH_NODE *op2;
    struct tac_node *next;
    struct tac_node *prev;
} TAC;

/**
 * Creates a TAC structure.
 *
 * <p>
 * A TAC structure is composed by the fields type, res, op1, op2, next and prev, where:
 *
 * <ul>
 *  <li><b>type:</b></li> used to identify the instrunction represented by the TAC.
 * Some TACs do not reflect an assembler instrunction, like TAC_REF, that is used
 * just to mark a memory reference situation.
 *  <li><b>res:</b></li> holds a memory reference where the operation result will be stored.
 *  <li><b>op1:</b></li> first operating
 *  <li><b>op2:</b></li> second operating
 *  <li><b>next:</b></li> pointer to the next TAC instrunction
 *  <li><b>prev:</b></li> pointer to the previous TAC instrunction
 * </ul>
 *
 * </p>
 *
 * @param type
 * @param res
 * @param op1
 * @param op2
 * @return
 */
TAC *tac_create(int type, HASH_NODE *res, HASH_NODE *op1, HASH_NODE *op2);

/**
 * Concatenate two lists of TACs.
 *
 * <p>
 * This function is used to generate a list of TAC instrunctions, this instrunctions
 * will be compiled to assembler code.
 * </p>
 *
 * @param l1
 * @param l2
 * @return
 */
TAC *tac_join(TAC *l1, TAC *l2);

/**
 * Reverse the list of TACs.
 *
 * <p>
 * The list of TACs is generated inverted, the reverse will reorder the TACs to generate
 * the correct assembler code.
 * </p>
 *
 * @param list
 * @return
 */
void tac_reverse(TAC *list);

/**
 * Prints a list of TACs
 * @param list
 */
void tac_print(TAC *list);

/**
 * Print a single TAC
 * @param t
 */
void tac_print_single(TAC *t);

TAC* tac_get_first(TAC *list);


#endif	/* TAC_H */



